<template>
  <div class="compression">
    <go-back></go-back>
    <main class="main-wrapper">
      <el-form ref="form" :model="form" label-width="auto">
        <el-form-item label="压缩强度">
          <el-slider
            v-model="form.intensity"
            :min="2.5"
            :max="10"
            :step="10 / 4"
            :marks="marks"
            :format-tooltip="formatTooltip"
            show-stops></el-slider>
        </el-form-item>
        <el-form-item label="文件列表">
          <el-upload
            class="upload-picture"
            drag
            action="#"
            multiple
            ref="upload"
            accept=".jpg,.jpeg,.png"
            :auto-upload="false"
            :show-file-list="false"
            :file-list="form.fileList"
            :on-change="onChange"
            v-show="!form.fileList.length">
            <i class="el-icon-upload"></i>
            <div class="el-upload__text">
              <div>
                将文件拖到此处，或
                <em>点击上传</em>
              </div>
              <div>最多上传10个JPG/JPEG/PNG文件，单个不超过20MB</div>
            </div>
          </el-upload>
          <ul class="file-list">
            <li
              class="file-item"
              v-for="item in form.fileList"
              :key="item.uid"
              :title="item.name">
              <!-- <div
                class="progress"
                :style="{
                  width: 32 + '%'
                }"></div> -->
              <el-row
                class="content"
                :gutter="20"
                type="flex"
                justify="space-between">
                <el-col :span="4" class="file-name">{{ item.name }}</el-col>
                <el-col :span="4">{{ item.width }}×{{ item.height }}</el-col>
                <el-col :span="8">
                  {{ item.originFileSize
                  }}{{ item.fileSize ? ` -> ${item.fileSize}` : '' }}
                </el-col>
                <el-col :span="4">
                  <el-tag
                    :type="['info', 'primary', 'success'][item.handleStatus]"
                    effect="dark">
                    <i
                      class="el-icon-loading"
                      v-if="item.handleStatus === 1"></i>
                    {{ ['待处理', '处理中', '处理成功'][item.handleStatus] }}
                  </el-tag>
                </el-col>
                <el-col :span="1" v-if="item.handleStatus === 0">
                  <i class="el-icon-close" @click="delFile(item)"></i>
                </el-col>
                <el-col :span="1" v-if="item.handleStatus === 2">
                  <i class="el-icon-download" @click="downloadFile(item)"></i>
                </el-col>
              </el-row>
            </li>
          </ul>
        </el-form-item>
        <el-form-item>
          <div class="func">
            <template v-if="!timeConsuming">
              <el-upload
                action="#"
                multiple
                accept=".jpg,.jpeg,.png"
                :auto-upload="false"
                :show-file-list="false"
                :on-change="onChange">
                <el-button type="primary" icon="el-icon-plus">
                  添加文件
                </el-button>
              </el-upload>
              <div>
                <el-button type="info" icon="el-icon-delete" @click="clearTask">
                  清空任务
                </el-button>
                <el-button type="primary" @click="startCompression">
                  开始处理
                  <i class="el-icon-right el-icon--right"></i>
                </el-button>
              </div>
            </template>
            <template v-else>
              <div>
                {{ form.fileList.length }}个任务处理完成，耗时{{
                  timeConsuming
                }}
              </div>
              <div>
                <el-button type="info" icon="el-icon-delete" @click="clearTask">
                  清空任务
                </el-button>
                <el-button
                  type="primary"
                  icon="el-icon-delete"
                  @click="packageDownload">
                  打包下载
                  <i class="el-icon-download"></i>
                </el-button>
              </div>
            </template>
          </div>
        </el-form-item>
      </el-form>
    </main>
  </div>
</template>
<script>
export default {
  name: 'compression',
  data() {
    return {
      marks: {
        2.5: '轻度',
        5: '常规',
        7.5: '强力',
        10: '极强'
      },
      form: {
        intensity: 5,
        fileList: []
      },
      // 压缩强度列表
      intensityList: [0.9, 0.6, 0.3, 0.1],
      // 压缩的强度
      intensityType: 0.7,
      timeConsuming: ''
    }
  },
  created() {
    this.initSlider(this.form.intensity)
  },
  methods: {
    /**
     * 初始化slider
     * @param {Number} value slider的value
     */
    initSlider(value) {
      const { marks } = this
      const index = Object.keys(marks)
        .sort((a, b) => a - b)
        .findIndex(item => Number(item) === value)
      this.intensityType = this.intensityList[index]
    },
    /**
     * 格式化slider显示文字
     */
    formatTooltip(value) {
      this.initSlider(value)
      return {
        2.5: '最佳质量',
        5: '较高质量',
        7.5: '较低质量',
        10: '低质量'
      }[value]
    },
    checkFileSuffix(name) {
      let suffix = name.substring(name.lastIndexOf('.') + 1, name.length)
      let suffixArr = ['jpg', 'jpeg', 'png']
      if (suffixArr.includes(suffix.toLowerCase())) {
        return true
      }
      return false
    },
    async onChange(file) {
      const IS_ACCORD_WITH = this.checkFileSuffix(file.name)
      if (!IS_ACCORD_WITH) {
        this.$refs.upload.uploadFiles = this.$refs.upload.uploadFiles.filter(
          item => item.name !== file.name && item.uid !== file.uid
        )
        return this.msgWrg('请上传指定的图片格式')
      }

      // 图片大小不能超过20M
      if (file.size / 1024 / 1024 > 20) {
        this.$refs.upload.uploadFiles = this.$refs.upload.uploadFiles.filter(
          item => item.name !== file.name && item.uid !== file.uid
        )
        return this.msgWrg('图片大小不能超过20M')
      }

      // 1MB
      const FILE_SIZE = file.size / 1024 / 1024

      // MB
      if (FILE_SIZE < 1) {
        file['originFileSize'] = `${FILE_SIZE.toFixed(2)}mb`
      }

      // KB
      if (FILE_SIZE > 0) {
        file['originFileSize'] = `${(FILE_SIZE * 1024).toFixed(2)}kb`
      }

      const imgInfo = await this.$utils.getImageInfo(file.raw)
      file['width'] = imgInfo.width
      file['height'] = imgInfo.height
      file['handleStatus'] = 0

      this.form.fileList.push(file)
    },
    delFile(item) {
      this.form.fileList = this.form.fileList.filter(
        file => file.uid !== item.uid && item.name !== file.name
      )
      if (!this.form.fileList) {
        this.clearTask()
      }
    },
    downloadFile(row) {
      this.$utils.downloadFile(row.base64, row.name)
    },
    async startCompression() {
      if (this.form.fileList.length < 1) {
        return this.msgErr('请上传图片！')
      }
      let handleCount = 0
      const firstTime = +new Date()
      for (let k = 0; k < this.form.fileList.length; k++) {
        const file = this.form.fileList[k]
        // 处理状态
        this.$set(this.form.fileList[k], 'handleStatus', 1)
        this.$forceUpdate()

        const base64 = await this.$utils.compressImage(file.raw, {
          quality: this.intensityType,
          // file.raw.type
          imageType: 'image/jpeg'
        })

        this.$set(this.form.fileList[k], 'base64', base64)

        // 1MB
        const FILE_SIZE = this.$utils.base64ToBlob(base64).size / 1024 / 1024

        // MB
        if (FILE_SIZE < 1) {
          this.$set(
            this.form.fileList[k],
            'fileSize',
            `${FILE_SIZE.toFixed(2)}mb`
          )
        }

        // KB
        if (FILE_SIZE > 0) {
          this.$set(
            this.form.fileList[k],
            'fileSize',
            `${(FILE_SIZE * 1024).toFixed(2)}kb`
          )
        }

        // 处理状态
        this.$set(this.form.fileList[k], 'handleStatus', 2)
        this.$forceUpdate()

        handleCount++
        if (handleCount >= this.form.fileList.length) {
          const lastTime = +new Date()
          this.timeConsuming = `${(lastTime - firstTime) / 1000}秒`
        }
      }
    },
    clearTask() {
      this.$refs.upload.clearFiles()
      this.form.fileList = []
      this.timeConsuming = ''
    },
    packageDownload() {
      this.$utils.downloadZip(this.form.fileList)
    }
  }
}
</script>
<style lang="scss" scoped>
.compression {
  position: relative;
  width: 100%;
  padding-top: 30px;
  color: var(--text-color);
  /deep/.el-form {
    display: flex;
    flex-direction: column;
    gap: 10px;
    width: 100%;
    max-width: 700px;
    .el-form-item__label,
    .el-upload__tip {
      color: inherit;
    }
    .el-slider__marks-text {
      white-space: nowrap;
    }
    .el-slider {
      width: 100%;
      padding: 0 15px;
    }
    .upload-picture {
      .el-upload-dragger,
      .el-upload {
        width: 100%;
      }
    }
    .file-list {
      border-radius: 8px;
      overflow: hidden auto;
      width: 100%;
      max-height: 300px;
      background: rgba(0, 0, 0, 0.2);
      .file-item + .file-item {
        border-top: 1px solid rgba(255, 255, 255, 0.5);
      }
      .file-item {
        position: relative;
        display: flex;
        justify-content: space-between;
        align-items: center;
        height: 40px;
        .progress {
          position: absolute;
          width: 100%;
          height: 100%;
          top: 0;
          left: 0;
          z-index: 1;
          background: rgba(48, 199, 254, 0.6);
        }
        .content {
          position: absolute;
          width: 100%;
          height: 100%;
          top: 0;
          left: 0;
          z-index: 2;
          padding: 5px;
          align-items: center;
          margin: 0 !important;
          .el-col + .el-col {
            display: flex;
            justify-content: center;
          }
          .file-name {
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
            flex: 1;
          }
          .specification {
            display: flex;
            align-items: center;
            justify-content: flex-end;
            gap: 20px;
          }
          [class^='el-icon'] {
            display: flex;
            align-items: center;
            justify-content: center;
            cursor: pointer;
          }
        }
      }
    }
    .func {
      display: flex;
      align-items: center;
      justify-content: space-between;
    }
  }
}
</style>
